#pragma once
class CNode;
class CTimer
{ 
	friend class CScheduleManager;
public:
	TIMER_TYPE m_dwTimerType;
	DWORD m_dwStartTime;
	DWORD m_dwPeriod;
	CNode *m_pHandler;
	__int64 m_nTimerId;
	bool m_bValid;
private:
	CTimer(const TIMER_TYPE dwType, const DWORD dwStartTime, const DWORD dwPeriod, CNode * pNode);
	CTimer(const CTimer& cTimer)
		:m_dwTimerType(cTimer.m_dwTimerType)
		,m_dwStartTime(cTimer.m_dwStartTime)
		,m_dwPeriod(cTimer.m_dwPeriod)
		,m_pHandler(cTimer.m_pHandler)
		,m_nTimerId(cTimer.m_nTimerId)
		,m_bValid(cTimer.m_bValid)
	{
	};
};
class CScheduleManager
{
	friend class CGlobalOperator;
public:
	CScheduleManager(const char *pStr = NULL);
	~CScheduleManager(void);
	bool AddTimer(const TIMER_TYPE dwType,const  DWORD dwStartTime, const DWORD dwPeriod, CNode * pNode);
	void Run(DWORD dwMaxDuration);
	bool KillTimer(const TIMER_TYPE dwType, CNode * pNode);
	bool InitNodeBehavior(const vector<CNodeBehavior>  & cBehaviorVector);


private:
	struct less
	{
		bool operator()(const pair<DWORD,CTimer *> &cLeft,const pair<DWORD,CTimer *>  & cRight)
		{
			if(cLeft.first==cRight.first)
			{
				return (DWORD)(cLeft.second)<(DWORD)(cRight.second);
			}
			else
			{
				return cLeft.first<cRight.first;
			}
		};
	};
	set<pair<DWORD,CTimer *> ,less> m_cExecuteQueue;
	map<NODE_INDEX,map<TIMER_TYPE,CTimer *>> m_cTimerHolder;

//join and leave -----------------------------------------------------------------------
	map<DWORD ,vector<pair<NODE_INDEX,DWORD>>> m_cNodeBehaviorInfo;
	map<NODE_INDEX,CNode*> m_cOnlineNodeList;
	bool KillAllTimer(CNode * pNode);
//monitor
	CNode *m_pGlobalOperator;
public:
	inline unsigned int GetNetworkSize()const
	{
		return m_cOnlineNodeList.size();
	}
	inline void GetOnlineNode(vector<CNode*> & cRes)
	{
		cRes.clear();
		for(map<NODE_INDEX,CNode*>::iterator it =m_cOnlineNodeList.begin();it!=m_cOnlineNodeList.end();++it)
		{
			cRes.push_back(it->second);
		}
	};
	CNode* GetRandomNode(void);
	CNode * GetNode(NODE_INDEX nIndex);
};
